package com.hyt.it.ogt.ks.job;

import com.hyt.core.util.StringUtils;
import com.hyt.it.ogt.ks.service.Event.CandidateAnswerLogEvent;
import com.hyt.it.ogt.ks.service.es.IEsAndDbService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * 定时刷新缓存中保存作答的轨迹
 *
 * @author 刘恒活
 * @since 2021/10/27 16:04
 */
@Component
@Slf4j
public class TaskJob implements InitializingBean {

    @Resource
    private ApplicationEventPublisher applicationEventPublisher;
    @Resource
    private CandidateAnswerBackupTask candidateAnswerBackupTask;
    @Resource
    private CandidateLogBackupTask candidateLogBackupTask;
    @Value("${saveCandidateAnswerLogJob.value:}")
    private String saveCandidateAnswerLogJob;
    @Resource
    private IEsAndDbService esAndDbService;

    /**
     * 指定参数需要删除多少天之前的数据：beforeDays=天
     *
     * @param params xxljob指定参数
     */
    @XxlJob("deleteApplyCheck")
    public void deleteApplyCheck(String params) {
        params = StringUtils.isEmpty(XxlJobHelper.getJobParam()) ? params : XxlJobHelper.getJobParam();
        log.info("=====指定参数需要删除多少天之前的异常审核数据开始 {}=====", params);
        Integer beforeDays = null;
        try {
            String[] paramArr = params.split("&");
            for (String param : paramArr) {
                String[] paramNameAndValue = param.split("=");
                if (Objects.equals(paramNameAndValue[0], "beforeDays")) {
                    beforeDays = Integer.parseInt(paramNameAndValue[1]);
                    break;
                }
            }
        } catch (Exception e) {
            log.error("解析参数报错：", e);
            return;
        }

        if (beforeDays == null) {
            log.error("参数为空");
            return;
        }

        esAndDbService.deleteApplyCheckByBeforeDays(beforeDays);
        log.info("=====指定参数需要删除多少天之前的异常审核数据结束 {}=====", params);
    }

    /**
     * 指定参数需要删除多少天之前的数据：beforeDays=天
     *
     * @param params xxljob指定参数
     */
    @XxlJob("deleteLogOther")
    public void deleteLogOther(String params) {
        params = StringUtils.isEmpty(XxlJobHelper.getJobParam()) ? params : XxlJobHelper.getJobParam();
        log.info("=====指定参数需要删除多少天之前的异常数据开始 {}=====", params);
        Integer beforeDays = null;
        try {
            String[] paramArr = params.split("&");
            for (String param : paramArr) {
                String[] paramNameAndValue = param.split("=");
                if (Objects.equals(paramNameAndValue[0], "beforeDays")) {
                    beforeDays = Integer.parseInt(paramNameAndValue[1]);
                    break;
                }
            }
        } catch (Exception e) {
            log.error("解析参数报错：", e);
            return;
        }

        if (beforeDays == null) {
            log.error("参数为空");
            return;
        }

        esAndDbService.deleteLogOtherByBeforeDays(beforeDays);
        log.info("=====指定参数需要删除多少天之前的异常数据结束 {}=====", params);
    }

    /**
     * 指定参数：examId=考试id&candidateIds=考生1id,考生2id
     * 考试id必须指定 考生id不指定默认所有
     * 支持：examId=考试id
     *      examId=考试id&candidateIds=考生1id,考生2id
     *      examId=考试id&candidateIds=
     *
     * @param params xxljob指定参数
     */
    @XxlJob("updateLogOther")
    public void updateLogOther(String params) {
        params = StringUtils.isEmpty(XxlJobHelper.getJobParam()) ? params : XxlJobHelper.getJobParam();
        log.info("=====更新指定考场指定考生异常数据开始 {}=====", params);
        String examId = null;
        List<String> candidateIds = new LinkedList<>();
        try {
            String[] paramArr = params.split("&");
            for (String param : paramArr) {
                String[] paramNameAndValue = param.split("=");
                if (Objects.equals(paramNameAndValue[0], "examId")) {
                    examId = paramNameAndValue[1];
                }
                if (Objects.equals(paramNameAndValue[0], "candidateIds")) {
                    String[] candidateIdArr = paramNameAndValue[1].trim().split(",");
                    candidateIds.addAll(Arrays.asList(candidateIdArr));
                }
            }

        } catch (Exception e) {
            log.error("解析参数报错：", e);
        }

        if (StringUtils.isEmpty(examId)) {
            return;
        }

        esAndDbService.importLogOther2eS(examId, candidateIds);
        log.info("=====更新指定考场指定考生异常数据开始=====");
    }

    /**
     * 指定参数：examId=考试id&candidateIds=考生1id,考生2id
     * 考试id必须指定 考生id不指定默认所有
     * 支持：examId=考试id
     *      examId=考试id&candidateIds=考生1id,考生2id
     *      examId=考试id&candidateIds=
     *
     * @param params xxljob指定参数
     */
    @XxlJob("updateApplyCheck")
    public void updateApplyCheck(String params) {
        params = StringUtils.isEmpty(XxlJobHelper.getJobParam()) ? params : XxlJobHelper.getJobParam();
        log.info("=====更新指定考场指定考生异常审核数据开始 {}=====", params);
        String examId = null;
        List<String> candidateIds = new LinkedList<>();
        try {
            String[] paramArr = params.split("&");
            for (String param : paramArr) {
                String[] paramNameAndValue = param.split("=");
                if (Objects.equals(paramNameAndValue[0], "examId")) {
                    examId = paramNameAndValue[1];
                }
                if (Objects.equals(paramNameAndValue[0], "candidateIds")) {
                    String[] candidateIdArr = paramNameAndValue[1].trim().split(",");
                    candidateIds.addAll(Arrays.asList(candidateIdArr));
                }
            }

        } catch (Exception e) {
            log.error("解析参数报错：", e);
        }

        if (StringUtils.isEmpty(examId)) {
            return;
        }

        esAndDbService.importApplyCheck2eS(examId, candidateIds);
        log.info("=====更新指定考场指定考生异常审核数据开始=====");
    }

    @XxlJob("saveCandidateAnswerLogJob")
    public void saveCandidateAnswerLogJob() {
        log.info("=====定时调度任务，调用考生答案推送启动=====");
        try {
            applicationEventPublisher.publishEvent(new CandidateAnswerLogEvent(1));
            log.info("=====定时调度任务，调用考生答案推送启动完成=====");
        } catch (Exception e) {
            log.error("定时高度任务,调用考生答案启动,执行任务发生异常:", e);
        }
    }

    /**
     * 考生事件记录备份任务
     */
    @XxlJob("backupCandidateLogJob")
    public void backupCandidateLogJob(){
        log.info("=======定时调度任务，调用考生事件记录表进行备份启动=====");
        try {
            candidateLogBackupTask.backupLog();
            log.info("=======定时调度任务，调用考生事件记录表进行备份完成=====");
        } catch (Exception e){
            log.error("定时调度任务，调用考生事件记录表进行备份任务发生异常:", e);
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if(!com.hyt.core.util.StringUtils.isEmpty(saveCandidateAnswerLogJob)) {
            XxlJob xxlJob = this.getClass().getDeclaredMethod("saveCandidateAnswerLogJob").getAnnotation(XxlJob.class);
            InvocationHandler invocationHandler = Proxy.getInvocationHandler(xxlJob);
            Field declaredField = invocationHandler.getClass().getDeclaredField("memberValues");
            declaredField.setAccessible(true);
            Map memberValues = (Map) declaredField.get(invocationHandler);
            memberValues.put("value", xxlJob.value() + saveCandidateAnswerLogJob);
        }
    }

    /**
     * 考生答题表备份任务
     */
    @XxlJob("backupCandidateAnswerJob")
    public void backupCandidateAnswerJob(){
        log.info("=======定时调度任务，调用考生答题表进行备份启动=====");
        try {
            candidateAnswerBackupTask.backupAnswer();
            log.info("=======定时调度任务，调用考生答题表进行备份完成=====");
        } catch (Exception e){
            log.error("定时调度任务，调用考生答题表进行备份任务发生异常:", e);
        }
    }

    @XxlJob("getReportAndSendScoreForXYJob")
    public void getReportAndSendScoreForXYJob() {
        log.info("=====定时调度任务，兴业银行获取报告推送成绩启动=====");
        try {
            //applicationEventPublisher.publishEvent(new ReportAndSendSocreDayiEvent(1));
        } catch (Exception e) {
            log.error("定时高度任务,兴业银行获取报告推送成绩启动,执行任务发生异常:", e);
        }
    }
}
